package threadtest;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import static threadtest.P.print;

/**
 * @author: mornd
 * <p>
 * runAfterBoth  a任务执行完，执行b任务，两个都执行完，回调runnable任务
 * thenAcceptBoth 接收a任务和b任务的结果
 * thenCombine  接收a任务和b任务的结果,并返回新结果
 *
 * runAfterEither a,b两任务其中一个执行就行
 * acceptEither 接收一个参数，那就是先执行完任务的结果
 * applyToEither 接收一个参数，那就是先执行完任务的结果，并返回新结果
 */
public class CompletableFutureTest2 {
    static final ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5,
            20,
            10, TimeUnit.SECONDS,
            new LinkedBlockingQueue<>(1000));

    public static void main2(String[] args) throws Exception {
        print("main start");

        CompletableFuture<Integer> c1 = CompletableFuture.supplyAsync(() -> {
            print("running c1");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
//            int a = 1/0;
            return 101;
        }, threadPoolExecutor);
        CompletableFuture<Integer> c2 = CompletableFuture.supplyAsync(() -> {
            print("running c2");
            return 102;
        }, threadPoolExecutor);

//        CompletableFuture<Void> c3_1 = c1.runAfterBoth(c2, () -> print("finally run"));
//        CompletableFuture<Void> c3_2 = c1.thenAcceptBoth(c2, (r1, r2) -> print("finally run,r1=" + r1 + ",r2=" + r2));
        CompletableFuture<String> c3_3 = c1.thenCombine(c2, (r1, r2) -> {
            print("finally run,r1=" + r1 + ",r2=" + r2);
            return "new Result";
        });
        print(c3_3.get());

        print("main end");
    }

    public static void main(String[] args) {
        print("main start");

        CompletableFuture<Integer> c1 = CompletableFuture.supplyAsync(() -> {
            print("running c1");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
//            int a = 1/0;
            return 101;
        }, threadPoolExecutor);
        CompletableFuture<Integer> c2 = CompletableFuture.supplyAsync(() -> {
            print("running c2");
            return 102;
        }, threadPoolExecutor);

//        CompletableFuture<Void> c3_1 = c1.runAfterEither(c2, () -> print("finally run"));
//        CompletableFuture<Void> c3_2 = c1.acceptEither(c2, (r) -> print("finally run,r1=" + r));
        CompletableFuture<String> c3_3 = c1.applyToEither(c2, (r) -> {
            print("finally run,r=" + r);
            return "new Result";
        });

        print("main end");
    }
}
